#include <fstream>
#include "Interpolation.h"
using namespace std;
const static double pi =3.141593;

void writeResultsToFile(const std::vector<double>& results,const std::string& filename) {  
    std::ofstream file(filename,std::ios::app); // 创建一个输出文件流对象  
    if (file.is_open()) {  
        for (const auto& result : results) {  
            file << result << " ";  
        }  
        file << " " <<endl;

        std::cout << "成功输入" << filename << std::endl;  
        file.close(); 
    } else {  
        std::cout << "无法打开文件："<< std::endl;  
    }  
}


class FB : public Function{
public:
    double operator() (const double &x) const{
        return 1/(1+x*x);
    }

}fb;

class FC : public Function{
public:
    double operator() (const double &x) const{
        return 1/(1+25*x*x);
    }

}fc;

//设置结点和函数值
class SetPoint{
private:
    Function &f;
    
    //左端点
    double left;

    //右端点
    double right;

    //x0,...xn
    int n;
    int choice;
public:
    vector<double> x;
    vector<double> fx;

    SetPoint(double left, double right ,int n, Function &f,int choice):
    left(left),right(right),n(n),f(f),choice(choice) {
        
        if(choice){
            x.resize(n + 1); // Resize x vector to accommodate n + 1 elements  
            fx.resize(n + 1);
            Average_Set();
            Set_fx_value();
        }
        else {
            x.resize(n); // Resize x vector to accommodate n + 1 elements  
            fx.resize(n);
            Chebychev_Set();
            Set_fx_value();
        }

    }

    //平均间隔插值
    void Average_Set(){
        double h =(right - left)/n;
        for(int i=0;i<=n;i++){
           x[i] = left + i * h;
        }
    }

    //Chebychev多项式插值
    void Chebychev_Set(){
        for(int i=1;i<=n;i++){
            x[i-1] = cos((2*i-1) * pi/(2*n));
        }
    }

    //设置函数值
    void Set_fx_value(){
        for(int i=0;i<x.size();i++){
            fx[i]= f(x[i]);
        }
    }

};



void programme_b(){
    SetPoint set1(-5.0 , 5.0 ,2 ,fb,1);
    Newton_Inter fb1(set1.x,set1.fx);
    writeResultsToFile(set1.x,"polyb.txt");
    writeResultsToFile(fb1.coefft,"polyb.txt");

    SetPoint set2(-5.0 , 5.0 ,4 ,fb,1);
    Newton_Inter fb2(set2.x,set2.fx);
    writeResultsToFile(set2.x,"polyb.txt");
    writeResultsToFile(fb2.coefft,"polyb.txt");
    
    SetPoint set3(-5.0 , 5.0 ,6 ,fb,1);
    Newton_Inter fb3(set3.x,set3.fx);
    writeResultsToFile(set3.x,"polyb.txt");
    writeResultsToFile(fb3.coefft,"polyb.txt");

    SetPoint set4(-5.0 , 5.0 ,8 ,fb,1);
    Newton_Inter fb4(set4.x,set4.fx);
    writeResultsToFile(set4.x,"polyb.txt");
    writeResultsToFile(fb4.coefft,"polyb.txt");
}


void programme_c(){
    SetPoint set1(-1.0,1.0 ,5,fc,0);
    Newton_Inter fb1(set1.x,set1.fx);
    writeResultsToFile(set1.x,"polyc.txt");
    writeResultsToFile(fb1.coefft,"polyc.txt");

    SetPoint set2(-1.0,1.0 ,10 ,fc,0);
    Newton_Inter fb2(set2.x,set2.fx);
    writeResultsToFile(set2.x,"polyc.txt");
    writeResultsToFile(fb2.coefft,"polyc.txt");

    SetPoint set3(-1.0,1.0,15 ,fc,0);
    Newton_Inter fb3(set3.x,set3.fx);
    writeResultsToFile(set3.x,"polyc.txt");
    writeResultsToFile(fb3.coefft,"polyc.txt");

    SetPoint set4(-1.0,1.0,20 ,fc,0);
    Newton_Inter fb4(set4.x,set4.fx);
    writeResultsToFile(set4.x,"polyc.txt");
    writeResultsToFile(fb4.coefft,"polyc.txt");
}


void programme_d(){ 
    vector<double> x1={0, 3, 5, 8, 13};
    vector<vector<double>> fx1={
        {0, 75},
        {225,77},
        {383,80},
        {623,74},
        {993,72}
    };
    vector<double>  fx2 ={75,77,80,74,72};
    
    Hermite pos(x1,fx1);
    writeResultsToFile(pos.xx_hmt,"polyd.txt");
    writeResultsToFile(pos.coefft,"polyd.txt");

    cout << "Its position for 10 seconds = "
    <<pos(10) << " feet "<< endl;

    cout << "Its speed for 10 seconds = "
    <<pos.diff(10)<< " feet per second "<< endl;

    cout << "Its speed for 6 seconds = "
    <<pos.diff(6)<< " feet per second "<< endl;
    cout << "在第六秒的时候汽车瞬时速度超过了81 feet/second,这辆车超速了" << endl;
}


void programme_e(){
    vector<double> day ={0,    6,    10,   13,   17,   20,   28};
    vector<double> sp1 ={6.67, 17.3, 42.7, 37.3, 30.1, 29.3, 28.7};
    vector<double> sp2 ={6.67,16.1,18.9,15.0,10.6,9.44,8.89};
    writeResultsToFile(day,"polye.txt");

    Newton_Inter weight1(day,sp1);
    Newton_Inter weight2(day,sp2);

    writeResultsToFile(weight1.coefft,"polye.txt");
    writeResultsToFile(weight2.coefft,"polye.txt");

    cout << "The average weight of sp1 after 15 days is weight1(43) = "
    << weight1(43) << endl;

     cout << "The average weight of sp2 after 15 days is weight2(43) = "
    << weight2(43) << endl;

    cout << "所以这两个样品再过15天后都不会死亡"<< endl;  
}

int main()
{
    cout << "Programme B" << endl;
    programme_b();
    cout << " " << endl;

    cout << "Programme C" << endl;
    programme_c();
    cout << " " << endl;

    cout << "Programme D" << endl;
    programme_d();
    cout << " " << endl;

    cout << "Programme E" <<endl;
    programme_e();
    cout << " "<< endl;

}